
#include <cstdio>
#include <BMap>
#include <BSpring>
#include <BSpacer>
#include <BApplication>

#include "ReadWrite_step.h"

ReadWrite_step::ReadWrite_step()
{
	_author = "zym";
	_version = "1.0";
	_description = "This is BWE Plugin for reading *.jpg image file, writen width libjpeg, thank a lot !";
}
ReadWrite_step::~ReadWrite_step()
{

}

void ReadWrite_step::setOptions(const BString& options)
{
	_options = options;
}
const BString& ReadWrite_step::options() const
{
	return _options;
}

const BString& ReadWrite_step::author() const
{
	return _author;
}
const BString& ReadWrite_step::version() const
{
	return _version;
}
const BString& ReadWrite_step::description() const
{
	return _description;
}
const BString& ReadWrite_step::message() const
{
	return _message;
}

inline bool isSpaceCode(char c)
{
	return c == ' '
		|| c == '\t'
		|| c == '\n'
		|| c == '\r'
		|| c == '\v';
}
inline void removeSpaceCode(BString& text)
{
	int begin = 0;
	int end = 0;
	while (1)
	{
		while (begin < text.size())
		{
			if (isSpaceCode(text[begin]))
				break;
			begin++;
		}
		if (begin == text.size())
			break;
		end = begin + 1;
		while (end < text.size())
		{
			if (!isSpaceCode(text[end]))
				break;
			end++;
		}
		text.remove(begin, end - begin);
		begin++;
		end = 0;
	}
}
inline bool readItem(const BFile& file, BString& text)
{
	text.reset();
	char code = 0;
	while (file.read(code))
	{
		text.append(code);
		if (code == ';')
			break;
	}
	return !text.empty();
}

BObject* ReadWrite_step::load(const BString& fileName)
{
	_pointMap.clear();
	_vectorMap.clear();
	_colorMap.clear();
	_directionMap.clear();

	BFile file(fileName);
	if (!file.open(IO_Read))
	{
		printf("STEP error -- read failed : %s\n", fileName.cstr());
		return 0;
	}

	BString text;
	if (!readItem(file, text))
	{
		printf("read step error : read first line text failed.\n");
		return 0;
	}

	text.trimmed();
	if (text != "ISO-10303-21;")
	{
		printf("read step error : format standar %s is not suported.\n", text.cstr());
		return 0;
	}

	while (readItem(file, text))
	{
		text.trimmed();
		if (text == "HEADER;")
		{
			if (false == readHeader(file))
				break;
			continue;
		}
		if (text == "DATA;")
		{
			if (false == readData(file))
				break;
			continue;
		}
		if (text == "END-ISO-10303-21;")
			break;
	}
	for (int i = 0; i < _edgeLoopTexts.size(); i++)
	{
		BString& text = _edgeLoopTexts[i];
		text.remove(0);
		int number = text.toInt();
		int pos = text.find('=');
		text.remove(0, pos + 1);
		text.trimmed();

		text.remove(0, 10);
		removeSpaceCode(text);
		text.remove('(');
		text -= ");";
		text.remove(0, text.find(',') + 1);
		text.remove('(');
		text -= ')';
		BStringList strlst;
		if (4 == text.split(strlst, ','))
		{
			QuadFace qface;
			strlst[0].remove('#');
			qface.ia = strlst[0].toInt();
			strlst[1].remove('#');
			qface.ib = strlst[1].toInt();
			strlst[2].remove('#');
			qface.ic = strlst[2].toInt();
			strlst[3].remove('#');
			qface.id = strlst[3].toInt();
			_quadMap.set(number, qface);
		}
	}
	BGeometry* geometry = new BGeometry();
	geometry->setColor(255, 0, 0);

	BVectorArray* vertices = new BVectorArray();
	for (auto it = _pointMap.begin(); it.valid(); it++)
	{
		const BVector& vec = (*it).vec;
		vertices->append(vec);
		(*it).index = vertices->size() - 1;
	}
	geometry->setVertices(vertices);

	BIndexArray* indices = new BIndexArray();
	for (auto it = _quadMap.begin(); it.valid(); it++)
	{
		QuadFace& qface = *it;
		indices->append(_pointMap(qface.ia).index);
		indices->append(_pointMap(qface.ib).index);
		indices->append(_pointMap(qface.ic).index);
		indices->append(_pointMap(qface.id).index);
	}
	BElement* element = new BElement(Primitive_Quads, indices);
	geometry->addElement(element);
	return geometry;
}
bool ReadWrite_step::load(const BString& fileName, BObject* object)
{
	if (!object)
		return false;

	BFile file(fileName);
	if (!file.open(IO_Read))
	{
		printf("STEP error -- read failed : %s\n", fileName.cstr());
		return false;
	}

	return false;
}
bool ReadWrite_step::save(const BString& fileName, const BObject* object) const
{
	if (!object)
		return false;

	BFile file(fileName);
	if (!file.open(IO_Write))
	{
		printf("STEP error -- write failed : %s\n", fileName.cstr());
		return false;
	}

	return false;
}

BObject* ReadWrite_step::read(const BBuffer& buffer)
{
	return 0;
}
bool ReadWrite_step::read(const BBuffer& buffer, BObject* object)
{
	return false;
}
bool ReadWrite_step::write(BBuffer& buffer, const BObject* object) const
{
	return false;
}

bool ReadWrite_step::readHeader(const BFile& file)
{
	BString text;
	while (readItem(file, text))
	{
		text.trimmed();
		if (text.beginWith("FILE_DESCRIPTION"))
		{
			text.remove(0, 17);
			BStringList strlst;
			if (2 == text.split(strlst, ','))
			{
				const BString& str0 = strlst(0);
				const BString& str1 = strlst(1);
			}
			continue;
		}
		if (text.beginWith("FILE_NAME"))
		{
			text.remove(0, 10);
			BStringList strlst;
			if (7 == text.split(strlst, ','))
			{
				const BString& str0 = strlst(0);
				const BString& str1 = strlst(1);
				const BString& str2 = strlst(2);
				const BString& str3 = strlst(3);
				const BString& str4 = strlst(4);
				const BString& str5 = strlst(5);
				const BString& str6 = strlst(6);
			}
			continue;
		}
		if (text.beginWith("FILE_SCHEMA"))
		{
			text.remove(0, 12);
			continue;
		}
		if (text == "ENDSEC;")
			return true;
	}
	return false;
}

bool ReadWrite_step::readData(const BFile& file)
{
	BString text;
	while (readItem(file, text))
	{
		text.trimmed();
		if (text == "ENDSEC;")
			return true;
		if (!text.beginWith('#'))
		{
			printf("data item not begin with '#' : %s.\n", text.cstr());
			return false;
		}
		if (text.contain("EDGE_LOOP"))
		{
			_edgeLoopTexts.append(text);
			continue;
		}
		text.remove(0);
		int number = text.toInt();
		int pos = text.find('=');
		text.remove(0, pos + 1);
		text.trimmed();
		if (text.beginWith("VECTOR"))
		{
			text.remove(0, 6);
			removeSpaceCode(text);
			text.remove('(');
			text -= ");";
			BStringList strlst;
			if (3 == text.split(strlst, ','))
			{
				const BString& strx = strlst[0];
				const BString& stry = strlst[1];
				const BString& strz = strlst[2];
			}
			continue;
		}
		if (text.beginWith("CARTESIAN_POINT"))
		{
			text.remove(0, 16);
			removeSpaceCode(text);
			text.remove('(');
			text -= ");";
			text.remove(0, text.find(',') + 1);
			text.remove('(');
			text -= ')';
			BStringList strlst;
			if (3 == text.split(strlst, ','))
			{
				PointCell cell;
				cell.vec.x() = strlst[0].toFloat();
				cell.vec.y() = strlst[1].toFloat();
				cell.vec.z() = strlst[2].toFloat();
				_pointMap.set(number, cell);
			}
			continue;
		}
		if (text.beginWith("COLOUR_RGB"))
		{
			text.remove(0, 16);
			removeSpaceCode(text);
			text.remove('(');
			text -= ");";
			text.remove(0, text.find(',') + 1);
			BStringList strlst;
			if (4 == text.split(strlst, ','))
			{
				BByte r = BByte(strlst[0].toFloat() * 255);
				BByte g = BByte(strlst[1].toFloat() * 255);
				BByte b = BByte(strlst[2].toFloat() * 255);
				_colorMap[number] = BColor(r, g, b);
			}
			continue;
		}
	}
	return false;
}

